// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: daniel

#include "coin2/exchange/base/api_base/fix/fix_message_utils.h"

#include <vector>

#include <glog/logging.h>

#include "quickfix/Message.h"
#include "quickfix/FieldMap.h"


namespace coin2::exchange::base::api_base::fix {

std::string FixMessageUtils::ToJson(const std::string& message_str) {
  try {
    FIX::Message message{message_str};
    return ToJson(message);
  } catch (FIX::Exception& ex) {
    // to nothing
  } catch (std::exception& ex) {
    // to nothing
  }
  return message_str;
}

std::string FixMessageUtils::ToJson(const FIX::Message& message) {
  const int space = 4;
  std::stringstream ss;
  ss << "{" << std::endl
     << std::setw(space) << " " << "\"header\": {" << std::endl
     << ToJsonFields(message.getHeader(), space)
     << std::setw(space) << " " << "}," << std::endl
     << std::setw(space) << " " << "\"body\": {" << std::endl
     << ToJsonFields(message, space)
     << std::setw(space) << " " << "}," << std::endl
     << std::setw(space) << " " << "\"trailer\": {" << std::endl
     << ToJsonFields(message.getTrailer(), space)
     << std::setw(space) << " " << "}" << std::endl
     << "}";

  return ss.str();
}

std::string FixMessageUtils::ToJsonFields(const FIX::FieldMap& fields, int space) {
  std::stringstream ss;
  FIX::FieldMap::const_iterator i;
  std::string name;
  for (i = fields.begin(); i != fields.end(); ++i) {
    int field = i->getTag();
    std::string value = i->getString();
    ss << std::setw(space + 4)
       << "\"" << field << "\"" << ":\"" << value << "\"," << std::endl;
  }

  FIX::FieldMap::g_const_iterator j;
  for (j = fields.g_begin(); j != fields.g_end(); ++j) {
    std::vector<FIX::FieldMap*>::const_iterator k;
    for (k = j->second.begin(); k != j->second.end(); ++k) {
      std::string group_name = "group";
      ss << std::setw(space + 4) << " " << "\"" << group_name << "\": {" << std::endl
         << ToJsonFields(*(*k), space + 4)
         << std::setw(space + 4) << " " << "}," << std::endl;
    }
  }

  return ss.str();
}

}  // namespace coin2::exchange::base::api_base::fix
